package cn.htsyb.synergy.security.entity;

import cn.htsyb.synergy.orm.jpa.model.entity.AbsStandardEntity;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.vladmihalcea.hibernate.type.array.BooleanArrayType;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.persistence.ForeignKey;
import jakarta.persistence.Table;
import jakarta.persistence.*;
import jakarta.validation.constraints.NotNull;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.hibernate.annotations.*;

import java.util.Date;
import java.util.List;

/**
 * 用户 实体类
 * @author lakeside hubin_yuan.410@hotmail.com
 * @version V1.0.0
 * @date 2022/5/23
 * @since 1.0
 */
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
@Setter
@Getter
@NoArgsConstructor
@DynamicInsert
@DynamicUpdate
@Entity(name = "SecurityUser")
@Table(name = "security_user")
@org.hibernate.annotations.Table(appliesTo = "security_user", comment = "用户")
@Schema(description = "用户")
public class SecurityUser extends AbsStandardEntity {
    private static final long serialVersionUID = 1L;

    /**
     * 头像
     */
    @Column(name = "avatar_url", length = 250, columnDefinition = " VARCHAR(250) COMMENT '头像' ")
    @Schema(name = "avatarUrl", description = "头像")
    protected String avatarUrl;
    /**
     * 身份证号
     */
    @Column(name = "card_id", length = 20, columnDefinition = " VARCHAR(20) COMMENT '身份证号' ")
    @Schema(name = "cardId", description = "身份证号")
    protected String cardId;
    /**
     * 邮箱
     */
    @Column(name = "email_", length = 50, columnDefinition = " VARCHAR(50) COMMENT '邮箱' ")
    @Schema(name = "email", description = "邮箱")
    protected String email;
    /**
     * 失效时间
     */
    @Column(name = "expired_time", columnDefinition = " DATETIME COMMENT '失效时间' ")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    @Schema(name = "expiredTime", description = "失效时间")
    protected Date expiredTime;

    /**
     * 员工工号
     */
    @Column(name = "job_code", length = 20, columnDefinition = " VARCHAR(20) COMMENT '员工工号' ")
    @Schema(name = "jobCode", description = "员工工号")
    protected String jobCode;

    /**
     * 员工职位
     */
    @Column(name = "job_post", length = 20, columnDefinition = " VARCHAR(20) COMMENT '员工职位' ")
    @Schema(name = "jobPost", description = "员工职位")
    protected String jobPost;
    /**
     * 领导者
     */
    @Column(name = "leader_id", length = 36, columnDefinition = " VARCHAR(36) COMMENT '领导者' ")
    @Schema(name = "leaderId", description = "领导者")
    protected String leaderId;
    /**
     * 手机号
     */
    @Column(name = "mobile_", length = 20, columnDefinition = " VARCHAR(20) COMMENT '手机号' ")
    @Schema(name = "mobile", description = "手机号")
    protected String mobile;
    /**
     * 归属组织主键
     */
    @Column(name = "organize_id", length = 36, columnDefinition = " VARCHAR(36) COMMENT '归属组织主键' ")
    @Schema(name = "organizeId", description = "归属组织主键")
    protected String organizeId;
    /**
     * 归属组织编码
     */
    @Column(name = "organize_code", length = 20, columnDefinition = " VARCHAR(20) COMMENT '归属组织编码' ")
    @Schema(name = "organizeCode", description = "归属组织编码")
    protected String organizeCode;
    /**
     * 用户名
     */
    @Column(name = "username_", nullable = false, length = 128, columnDefinition = " VARCHAR(128) COMMENT '用户名' ")
    @NotNull
    @Schema(name = "username", description = "用户名",  required = true)
    protected String username;
    /**
     * 密码
     */
    @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
    @Column(name = "password_", nullable = false, length = 128, columnDefinition = " VARCHAR(128) COMMENT '密码' ")
    @NotNull
    @Schema(name = "password", description = "密码",  required = true)
    protected String password;
    /**
     * 真实姓名
     */
    @Column(name = "real_name", length = 50, columnDefinition = " VARCHAR(50) COMMENT '真实姓名' ")
    @Schema(name = "realName", description = "真实姓名")
    protected String realName;

    /**
     * 是否内部配置(不显示给用户)
     */
    @Column(name = "has_inside", length = 1, columnDefinition = "TINYINT(1) COMMENT '是否内部配置' ")
    @Schema(name = "hasInside", description = "是否内部配置:true即不显示给用户")
    @Type(BooleanArrayType.class)
    protected Boolean hasInside = false;

    /**
     * 拥有的角色集合
     */
    @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
    @ManyToMany(fetch = FetchType.LAZY, targetEntity = SecurityRole.class)
    @NotFound(action = NotFoundAction.IGNORE)
    @JoinTable(name = "security_role_user",
            uniqueConstraints = {@UniqueConstraint(columnNames = {"user_id", "role_id"})},
            joinColumns = @JoinColumn(name = "user_id", nullable = false, updatable = false, insertable = false,
                    foreignKey = @ForeignKey(name = "none", value = ConstraintMode.NO_CONSTRAINT),
                    columnDefinition = "varchar(36) COMMENT '用户'"),
            inverseJoinColumns = @JoinColumn(name = "role_id", nullable = false, updatable = false, insertable = false,
                    foreignKey = @ForeignKey(name = "none", value = ConstraintMode.NO_CONSTRAINT),
                    columnDefinition = "varchar(36) COMMENT '角色'"))
    protected List<SecurityRole> roles;

    /**
     * 领导者回显
     */
    @Schema(name = "leaderIdName",description= "领导者回显")
    @Formula("(select hu.real_name from security_user hu where hu.id_=leader_id)")
    protected String leaderIdName;

    /**
     * 归属组织回显
     */
    @Schema(name = "organizeIdName", description = "归属组织回显")
    @Formula("(select ho.name_ from security_organize ho where ho.id_=organize_id)")
    protected String organizeIdName;
}